package com.ithema.dao;

import com.ithema.domain.Student;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/*
    库管类核心职责:
            1. 接收业务员传过来的业务数据
            2. 对业务数据进行增删改查操作  -- 操作系统数据容器: 数组
            3. 将操作后的结果返回给业务员
    容器升级: 将系统数据仓库由数组容器升级为集合容器
 */
public class StudentDao implements BaseStudentDao {

    //1. 创建一个数组容器,作为系统底层的数据仓库
    private static List<Student> stus = new ArrayList<>();

    //静态代码块: 随着类的加载而执行!只执行一次!
    static {
        //模拟加载数据功能: 将之前系统产生的数据,重新读回内存,存入数组
        System.out.println("--------------------loading----------------");
        reload02();
    }


    public boolean addStudent(Student stu) {
        stus.add(stu);
        //存档
        reSave02();
        return true;
    }

    //库管类中的查看学生功能
    public List<Student> findAllStudent() {
        return stus;
    }

    //库管类中的删除学生功能
    public boolean deleteStudent(String delId) {
        //1. 调用getIndex方法,查找当前id是否存在
        int index = getIndex(delId);

        //2. 根据index来决定是否能够删除成功
        if (index == -1) {
            //说明当前学号不存在,则无法删除,返回false即可
            return false;
        } else {
            //说明当前学号存在,将该学号对应的学生对象从数组中移除,然后返回true
            stus.remove(index);

            //存档
            reSave02();
            return true;
        }
    }

    //库管类中的修改学生功能
    public boolean updateStudent(String updateId, Student newStu) {
        //1. 调用getIndex方法,查找当前id是否存在
        int index = getIndex(updateId);

        //2. 根据index的值来决定能否修改成功
        if (index == -1) {
            //说明学号不存在,则返回false,表示修改失败
            return false;
        } else {
            //说明学号存在,直接将index记录的索引位置用newStu新的学生对象进行覆盖就达到了修改效果
            stus.set(index, newStu);
            //存档
            reSave02();
            return true;
        }
    }

    //封装一个方法: 根据学号查找对应的人在容器中的索引位置
    public int getIndex(String id) {
        //1. 标记位: 先假设要查找的学号不存在
        int index = -1;
        //2. 遍历容器
        for (int i = 0; i < stus.size(); i++) {
            //取出数组中每一个索引位置的元素
            Student stu = stus.get(i);

            //判断当前索引位置的元素的学号与要查找的学号是否相同
            if (stu != null && stu.getId().equals(id)) {
                index = i;      //相同则记录当前学生对象的索引位置
                break;
            }
        }

        //3. 返回index
        return index;
    }

    //封装一个方法: 基于字节输出流实现系统数据的存档功能
    public void reSave01() {
        try {
            //1. 创建一个字节输出流对象
            FileOutputStream fos = new FileOutputStream("itheima-edu-info-manager\\stu.txt");
            //2. 遍历集合
            for (int i = 0; i < stus.size(); i++) {
                //拿到每一个学生信息
                Student stu = stus.get(i);
                //获取stu对象的属性信息
                String stuStr = stu.toString();
                //将当前学生信息写到文件中,进行持久化存档
                fos.write(stuStr.getBytes());
                //写完一个学生信息后,就换一行
                fos.write(System.lineSeparator().getBytes());
            }
            //3. 关流
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //封装一个方法: 基于序列化流实现系统数据的存档功能
    public void reSave02(){
        try{
            //1. 创建序列化流对象
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("itheima-edu-info-manager\\stu.txt"));
            //2. 将集合写到文件
            oos.writeObject(stus);
            //3. 关流,释放资源
            oos.close();
        }catch (Exception e){}
    }

    //封装一个方法: 基于字节输入流实现系统存档数据的加载功能
    public static void reload01() {
        try {
            //1. 创建字节输入流对象,指向要读取的文件
            FileInputStream fis = new FileInputStream("itheima-edu-info-manager\\stu.txt");
            //2. 定义一个数组容器,这个容器要足够大,期望一次就把文件中所有字节都读取完毕
            byte[] bys = new byte[1024 * 1024];
            int len = fis.read(bys);
            //3. 将读到的所有字节数据封装为字符串
            String allStuMsg = new String(bys, 0, len);
            /*
                allStuMsg = "heima001,柳岩,36,1999-11-11
                             heima002,杨幂,35,1995-11-11
                             heima009,老酒,21,1999-11-11"
             */
            //4. 对allStuMsg进行切割处理
            /*
                stuStrArr = {"heima001,柳岩,36,1999-11-11",
                            "heima002,杨幂,35,1995-11-11",
                            "heima009,老酒,21,1999-11-11"}
             */
            String[] stuStrArr = allStuMsg.split(System.lineSeparator());
            //5. 遍历数组
            for (int i = 0; i < stuStrArr.length; i++) {
                //拿到每一个学生信息
                String[] split = stuStrArr[i].split(",");
                //封装学生对象
                Student stu = new Student(split[0], split[1], split[2], split[3]);
                //装载到集合
                stus.add(stu);
            }
            //6. 释放资源
            fis.close();
        } catch (Exception e) {
        }
    }

    //封装一个方法: 基于反序列化流实现系统存档数据的加载功能
    public static void reload02(){
        try{
            //1. 创建反序列化流对象
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("itheima-edu-info-manager\\stu.txt"));
            stus = (ArrayList<Student>) ois.readObject();
            ois.close();
        }catch (Exception e){}
    }

}
